<?php
/**
 * Created by PhpStorm.
 * User: guokunsheng
 * Date: 2022/5/25
 * Time: 上午10:49
 */

namespace app\api\controller\v32;

use app\api\controller\v13\Auth2;
use app\common\cachemodel\Article;
use app\common\cachemodel\ArticleRead;
use app\common\cachemodel\GoddessArea;
use app\common\cachemodel\lucky\AppUserAdornInfo;
use app\common\cachemodel\ZlGoddessState;
use app\common\lib\ConfigManage;
use app\common\lib\Util;
use app\common\model\ArticleGood;
use think\Env;
use think\Log;
use XznsTools\search\Elasticsearch as ElasticSearchTool;

/**
 * @version v2.8.5
 * Class Search
 * @package app\api\controller\v32
 */
class Search extends Auth2
{
    /**
     * 搜索
     */
    public function index()
    {
        $page = input('page/d', 1);
        $keyword = htmlspecialchars(trim(input('keyword/s', '')));
        $type = input('type/d', 2);
        $env = Env::get('host.name');

        switch ($type)
        {
            case 1:#话题搜索
                $index = $env . '_' . 'topic';
                /**
                 * es中仅存储 id,title,author,publish_time,sort 这些字段
                 */
                $fields = 'id,title,author,publish_time,sort';
                $sort = ['sort' => 'desc', 'publish_time' => 'desc', 'id' => 'desc'];
                $query = [
                    'must' => [
                        ['match' => ['title' => $keyword]],
                        ['range' => ['publish_time' => ['lte' => time()]]]
                    ],
                ];
                break;
            case 2:#星文搜索
                $index = $env . '_' . 'article';
                /**
                 * es中仅存储 id,title,author,introduction,publish_time,sort,content,type 这些字段
                 * type 文章类型 0=>星文,1=>女神动态图文
                 */
                $fields = 'id,title,author,introduction,publish_time,type';// ,content,sort
                $sort = ['sort' => 'desc', 'id' => 'desc'];
                $query = [
                    /**
                     * 进行检索时，必须满足的条件
                     */
                    'must' => [
                        ['multi_match' => ['query' => $keyword, 'type' => 'best_fields', 'fields' => ['title^4', 'introduction^3', 'author^2'],]],
                        /**
                         * 文章发布时间限制
                         * gt  >    大于
                         * gte >=   大于等于
                         * lt  <    小于
                         * lte <=   小于等于
                         */
                        ['range' => ['publish_time' => ['lte' => 'now/m']]],
                        /**
                         * 指定 字段-值 查询
                         */
//                        ['term' => []],
                    ],
                    /**
                     * 进行检索时，非必须满足的条件
                     */
//                'should' => []
                ];
                break;
            case 3:#视频搜索
                $index = $env . '_' . 'dynamic';
                /**
                 * es中仅存储 id,title,author,introduction,publish_time,sort 这些字段
                 */
                $fields = 'id,title,author,introduction,publish_time,sort';
                $sort = ['sort' => 'desc', 'id' => 'desc'];
                $query = [
                    'must' => [
                        ['multi_match' => ['query' => $keyword, 'type' => 'best_fields', 'fields' => ['title^4', 'introduction^3', 'author^2'],]],
                        ['range' => ['publish_time' => ['lte' => time()]]]
                    ],
                ];
                break;
            default:
                return show(config('code.error'), '未知的搜索');
                break;
        }

        $keyword !== '' ? $params = ['bool' => $query] : $params = [];

        try
        {
            $data = ElasticSearchTool::getInstance()
                // 设置需要检索的索引
                ->setIndex($index)
                // 设置分页查询每页显示的数量
                ->setPargeSize(10)
                // 设置分页时，需要查询的页码
                ->setPageNum($page)
                // 设置检索条件
                ->setParamWhere($params)
                // 设置检索结果需要返回的字段
                ->setParamFields($fields)
                // 设置检索结果排序条件
//                ->setParamSort($sort)
                ->search();
        }
        catch (Exception $e)
        {
            Log::write('搜索失败:' . $e->getMessage() . '[' . $e->getFile() . ':' . $e->getLine() . ']');
            return show(config('code.error'), '服务异常，请稍后重试～');
        }
        // 若搜索异常，报错
        if (isset($data['err_msg']) && $data['err_msg'] !== '')
        {
            return show(config('code.error'), '服务异常，请稍后重试～');
        }
        // 根据es查询出来的id，获取其他需要的数据
        if (isset($data['total']) && $data['total'] > 0)
        {
            $articleIds = [];
            $goddessStateArticleIds = [];
            $goddessStateVideoIds = [];
            $goddessTopicIds = [];

            foreach ($data['data'] as $k1 => $v1)
            {
                if ($type === 1)
                {
                    $goddessTopicIds[] = $v1['id'];
                } // 若为星文检索，则type=0表示星文，type=1表示女神动态图文，需要查询两个类型的值，再重新组合到一起
                elseif ($type === 2)
                {
                    if ($v1['type'] === 0)
                    {
                        $articleIds[] = $v1['id'];
                    } else
                    {
                        $goddessStateArticleIds[] = $v1['id'];
                    }
                } elseif ($type === 3)
                {
                    $goddessStateVideoIds[] = $v1['id'];
                }
            }
            $configModel = new ConfigManage();
            switch ($type)
            {
                case 1:
                    $goddessTopicDatas = (new GoddessArea())->batchGetThemeInfo($goddessTopicIds, ['id', 'is_hot', 'title', 'good_num', 'collect_num', 'comment_num', 'interaction_num', 'read_num']);
                    $processedData = [];
                    foreach ($goddessTopicDatas as $key => $goddessTopicData)
                    {
                        $processedData[$key] = [
                            'id' => (int)$goddessTopicData['id'],
                            'content' => $goddessTopicData['title'],
                            'is_hot' => (int)$goddessTopicData['is_hot'],
                            'desc' => ($goddessTopicData['good_num'] + $goddessTopicData['collect_num'] + $goddessTopicData['comment_num'] + $goddessTopicData['interaction_num'] + $goddessTopicData['read_num']) . '热度',
                        ];
                    }
                    $data['data'] = array_values($processedData);
                    break;
                case 2:#星文检索
                    if ($this->user['id'])
                    {
                        $goods = (new ArticleGood())->getGoodFromCache($this->user['id'], 1);
                        $reads = (new ArticleRead())->getUserArticleReadIds($this->user['id'], 1);
                        $goodsState = (new ArticleGood())->getGoodFromCache($this->user['id'], 2);
                        $readsState = (new ArticleRead())->getUserArticleReadIds($this->user['id'], 2);
                    }
                    $articleDatas = (new Article())->batchGetInfo($articleIds, ['id', 'title', 'introduction', 'author', 'avatar', 'thumb', 'publish_time', 'good', 'read', 'read_base', 'is_hot', 'a_id', 'author_type']);
                    foreach ($articleDatas as $key => $article)
                    {
                        //阅读数量计算
                        $readNum = ($article['read'] ?? 0) + ($article['read_base'] ?? 0);
                        // 点赞数量计算
                        $goodNum = ($article['good'] ?? 0) + floor($readNum / 30);
                        $articleDatas[$key]['target'] = 'local';
                        $articleDatas[$key]['link'] = "article_details?id={$article['id']}&type=1&need_auth=0";
                        $articleDatas[$key]['type'] = 1;
                        $articleDatas[$key]['publish_time'] = Util::timeToStr($article['publish_time']);
                        $articleDatas[$key]['is_read'] = !empty($reads) ? (in_array($article['id'], $reads, false) ? 1 : 0) : 0;
                        $articleDatas[$key]['is_good'] = !empty($goods) ? (in_array($article['id'], $goods, false) ? 1 : 0) : 0;
                        $articleDatas[$key]['good_num'] = $goodNum;
                        $articleDatas[$key]['read_num'] = $readNum;
                        $articleDatas[$key]['user_type'] = $configModel->innerUser((int)($article['a_id'] ?? 0));
                        // 获取作者当前装扮信息
                        $adorn = (new AppUserAdornInfo())->getUserAdornInfo(0, $article['author_type'] ?? 0);
                        $articleDatas[$key]['avatar_adorn'] = $adorn['adorn_info']['reality_img'];
                        unset($articleDatas[$key]['a_id'], $articleDatas[$key]['read'], $articleDatas[$key]['good']);
                    }
                    $goddessStateArticleDatas = (new ZlGoddessState())->batchGetInfoByIds($goddessStateArticleIds, ['id', 'title', 'introduction', 'author', 'avatar', 'thumb', 'publish_time', 'good_num', 'read_num', 'is_hot', 'a_id', 'type', 'target', 'link', 'author_type']);
                    foreach ($goddessStateArticleDatas as $key => $state)
                    {
                        if ($state['type'] == 6)
                        {
                            $goddessStateArticleDatas[$key]['target'] = $state['target'];
                            $goddessStateArticleDatas[$key]['link'] = $state['link'];
                            $urlData = parse_url($state['link']);
                            if (isset($urlData['query']))
                            {
                                $queryParts = explode('&', $urlData['query']);
                                $params = [];
                                foreach ($queryParts as $param)
                                {
                                    $item = explode('=', $param);
                                    $params[] = $item[0];
                                }
                                if (!in_array('type', $params, true))
                                {
                                    $goddessStateArticleDatas[$key]['link'] = $state['link'] . '&type=1';
                                }
                            }
                        } else
                        {
                            $goddessStateArticleDatas[$key]['target'] = 'local';
                            $goddessStateArticleDatas[$key]['link'] = "article_details?id={$state['id']}&type=2&need_auth=0";
                        }
                        $goddessStateArticleDatas[$key]['type'] = 2;
                        $goddessStateArticleDatas[$key]['publish_time'] = Util::timeToStr($state['publish_time']);
                        $goddessStateArticleDatas[$key]['is_read'] = !empty($readsState) ? (in_array($state['id'], $readsState, false) ? 1 : 0) : 0;
                        $goddessStateArticleDatas[$key]['is_good'] = !empty($goodsState) ? (in_array($state['id'], $goodsState, false) ? 1 : 0) : 0;
                        $goddessStateArticleDatas[$key]['good_num'] = $state['good_num'];
                        $goddessStateArticleDatas[$key]['read_num'] = $state['read_num'];
                        $goddessStateArticleDatas[$key]['user_type'] = $configModel->innerUser((int)($state['a_id'] ?? 0));
                        // 获取作者当前装扮信息
                        $adorn = (new AppUserAdornInfo())->getUserAdornInfo(0, $state['author_type'] ?? 0);
                        $goddessStateArticleDatas[$key]['avatar_adorn'] = $adorn['adorn_info']['reality_img'];
                        unset($goddessStateArticleDatas[$key]['a_id']);
                    }
                    $data['data'] = array_merge($articleDatas, $goddessStateArticleDatas);
                    break;
                case 3:
                    $goddessStateVideoDatas = (new ZlGoddessState())->batchGetInfoByIds($goddessStateVideoIds, ['status', 'id', 'type', 'url', 'duration', 'title', 'good_num', 'comment_num', 'collect_num', 'publish_time', 'introduction', 'content', 'thumb', 'thumb_width', 'thumb_height', 'url_des', 'is_recommend', 'read_num', 'read_base', 'author', 'avatar', 'a_id', 'target', 'link', 'mall_title', 'mall_img', 'mall_target', 'mall_link']);
                    $goddessStateVideoDatas = (new ZlGoddessState())->resetStateLIst($this->user, $goddessStateVideoIds, $goddessStateVideoDatas);
                    $data['data'] = array_values($goddessStateVideoDatas);
                    break;
            }
        }

        return show(config('code.success'), '加载成功', $data);
    }
}
